﻿// -----------------------------------------------------------------------
// <copyright file="ImeisControllerFixture.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace MobileTrack.Web.Tests.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Principal;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using System.Web.Security;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using MobileTrack.Core;
    using MobileTrack.Core.Data;
    using MobileTrack.Core.Model;
    using MobileTrack.Web.Controllers;
    using MobileTrack.Web.ViewModels;
    using Moq;

    [TestClass]
    public class ImeisControllerFixture
    {
        private IList<Celular> celulares;
        private IList<Marca> marcas;
        private IList<Sucursal> sucursales;
        private IList<Seguimiento> seguimientos;
        private IList<Abono> abonos;
        private IList<Venta> ventas;
        private string userRole;
        private bool isInRole;

        private Mock<IRepository<Celular>> celularesRepositoryMock;
        private Mock<IRepository<Marca>> marcasRepositoryMock;
        private Mock<IRepository<Sucursal>> sucursalesRepositoryMock;
        private Mock<IRepository<Seguimiento>> seguimientosRepositoryMock;
        private Mock<IRepository<Abono>> abonosRepositoryMock;
        private Mock<IRepository<Venta>> ventasRepositoryMock;
        private Mock<IRepositories> repositoriesMock;
        private Mock<IPrincipal> principalMock;

        [TestInitialize]
        public void TestInitialize()
        {
            this.celulares = new List<Celular>();
            this.marcas = new List<Marca>();
            this.sucursales = new List<Sucursal>();
            this.seguimientos = new List<Seguimiento>();
            this.abonos = new List<Abono>();
            this.ventas = new List<Venta>();
            this.userRole = string.Empty;
            this.isInRole = false;

            this.celularesRepositoryMock = new Mock<IRepository<Celular>>();
            this.celularesRepositoryMock.Setup(cr => cr.All).Returns(() => this.celulares.AsQueryable());

            this.marcasRepositoryMock = new Mock<IRepository<Marca>>();
            this.marcasRepositoryMock.Setup(mr => mr.All).Returns(() => this.marcas.AsQueryable());

            this.sucursalesRepositoryMock = new Mock<IRepository<Sucursal>>();
            this.sucursalesRepositoryMock.Setup(sr => sr.All).Returns(() => this.sucursales.AsQueryable());

            this.seguimientosRepositoryMock = new Mock<IRepository<Seguimiento>>();
            this.seguimientosRepositoryMock.Setup(ser => ser.All).Returns(() => this.seguimientos.AsQueryable());

            this.abonosRepositoryMock = new Mock<IRepository<Abono>>();
            this.abonosRepositoryMock.Setup(ar => ar.All).Returns(() => this.abonos.AsQueryable());

            this.ventasRepositoryMock = new Mock<IRepository<Venta>>();
            this.ventasRepositoryMock.Setup(vr => vr.All).Returns(() => this.ventas.AsQueryable());

            this.repositoriesMock = new Mock<IRepositories>();
            this.repositoriesMock.Setup(rs => rs.Celulares).Returns(() => this.celularesRepositoryMock.Object);
            this.repositoriesMock.Setup(rs => rs.Marcas).Returns(() => this.marcasRepositoryMock.Object);
            this.repositoriesMock.Setup(rs => rs.Sucursales).Returns(() => this.sucursalesRepositoryMock.Object);
            this.repositoriesMock.Setup(rs => rs.Seguimientos).Returns(() => this.seguimientosRepositoryMock.Object);
            this.repositoriesMock.Setup(rs => rs.Abonos).Returns(() => this.abonosRepositoryMock.Object);
            this.repositoriesMock.Setup(rs => rs.Ventas).Returns(() => this.ventasRepositoryMock.Object);

            this.principalMock = new Mock<IPrincipal>();
            this.principalMock.Setup(p => p.IsInRole(It.Is<string>(r => r.Equals(this.userRole, StringComparison.OrdinalIgnoreCase)))).Returns(() => this.isInRole);
        }

        [TestMethod]
        public void IndexShouldReturnFiltersInViewBag()
        {
            this.marcas.Add(new Marca { Id = 1, Codigo = 10, Nombre = "Marca1", EsOperador = true });
            this.marcas.Add(new Marca { Id = 2, Codigo = 20, Nombre = "Marca2", EsOperador = true });
            this.marcas.Add(new Marca { Id = 3, Codigo = 30, Nombre = "Marca3", EsOperador = false });

            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1", Direccion = "Dir1", Telefono = "Tel1" });
            this.sucursales.Add(new Sucursal { Id = 2, Codigo = "20", Nombre = "Suc2", Direccion = "Dir2", Telefono = "Tel2" });

            var controller = this.CreateImeisController();

            var result = controller.Index("producto:samsung") as ViewResult;
            Assert.IsNotNull(result);

            var filter = result.ViewBag.Filter as string;
            var operadores = result.ViewBag.OperadoresFilter as IEnumerable<string>;
            var estados = result.ViewBag.EstadosFilter as IEnumerable<string>;
            var sucursales = result.ViewBag.UbicacionesFilter as IEnumerable<string>;

            Assert.AreEqual("producto:samsung", filter);
            Assert.IsTrue(operadores.Count() == 2);
            Assert.IsTrue(operadores.Contains("Marca1"));
            Assert.IsTrue(operadores.Contains("Marca2"));
            Assert.IsFalse(operadores.Contains("Marca3"));
            Assert.IsTrue(estados.Count() == 6);
            Assert.IsTrue(estados.Contains("En Transito"));
            Assert.IsTrue(sucursales.Count() == 2);
            Assert.IsTrue(sucursales.Contains("Suc1"));
            Assert.IsTrue(sucursales.Contains("Suc2"));

            this.marcasRepositoryMock.VerifyAll();
            this.sucursalesRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void AssociateImeiShouldReturnEstadosInViewBag()
        {
            var controller = this.CreateImeisController();

            var result = controller.AssociateImei() as ViewResult;
            Assert.IsNotNull(result);

            var estados = result.ViewBag.EstadoList as IEnumerable<SelectListItem>;
            Assert.AreEqual(2, estados.Count());
            Assert.IsTrue(estados.Any(e => e.Text == "En Deposito"));
            Assert.IsTrue(estados.Any(e => e.Text == "Dañado"));
        }

        [TestMethod]
        public void AssociateImeiShouldReturnPartialViewWhenAjaxRequest()
        {
            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.AssociateImei() as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_AssociateImei", result.ViewName);
        }

        [TestMethod]
        public void AssociateImeiShouldSaveValidAssociation()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;

            var sucursal = "Sucursal";
            var userName = "Asociante";
            
            var today = DateTime.Today;
            var seg = new Seguimiento { Id = 1, CelularId = 1, Comprobante = "REM 0000-00000000", Fecha = today, Estado = Estado.Pendiente, EstadoInt = (int)Estado.Pendiente };
            var cel = new Celular { Id = 1, FechaIngreso = today.AddDays(-1) };
            cel.Seguimientos.Add(seg);
            this.celulares.Add(cel);

            var association = new AssociateImeiViewModel { Id = 1, Imei = 123456789123456, EstadoInt = (int)Estado.EnDeposito, Fecha = today };

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);
            
            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);

            var result = controller.AssociateImei(association) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void AssociateImeiShouldReturnPartialViewOnInvalidDate()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            var seg = new Seguimiento { Id = 1, CelularId = 1, Comprobante = "REM 0000-00000000", Fecha = today, Estado = Estado.Pendiente, EstadoInt = (int)Estado.Pendiente };
            var cel = new Celular { Id = 1, FechaIngreso = today.AddDays(-1) };
            cel.Seguimientos.Add(seg);
            this.celulares.Add(cel);

            var association = new AssociateImeiViewModel { Id = 1, Imei = 123456789123456, EstadoInt = (int)Estado.EnDeposito, Fecha = today.AddDays(-1) };

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(roleProvider: roleProviderMock.Object);

            var result = controller.AssociateImei(association) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_AssociateImei", result.ViewName);
        }

        [TestMethod]
        public void AssociateImeiShouldReturnPartialViewOnDuplicatedImei()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            var seg = new Seguimiento { Id = 1, CelularId = 1, Comprobante = "REM 0000-00000000", Fecha = today, Estado = Estado.Pendiente, EstadoInt = (int)Estado.Pendiente };
            var cel = new Celular { Id = 1, FechaIngreso = today.AddDays(-1) };
            var cel2 = new Celular { Id = 2, FechaIngreso = today.AddDays(-1), Imei = 123456789123456 };
            cel.Seguimientos.Add(seg);
            this.celulares.Add(cel);
            this.celulares.Add(cel2);

            var association = new AssociateImeiViewModel { Id = 1, Imei = 123456789123456, EstadoInt = (int)Estado.EnDeposito, Fecha = today.AddDays(-1) };

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(roleProvider: roleProviderMock.Object);

            var result = controller.AssociateImei(association) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_AssociateImei", result.ViewName);
        }

        [TestMethod]
        public void BulkSendShouldReturnSucursalesInViewBag()
        {
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1", Direccion = "Dir1", Telefono = "Tel1" });
            this.sucursales.Add(new Sucursal { Id = 2, Codigo = "20", Nombre = "Suc2", Direccion = "Dir2", Telefono = "Tel2" });

            var controller = this.CreateImeisController();

            var result = controller.BulkSend() as ViewResult;
            Assert.IsNotNull(result);

            var sucursales = result.ViewBag.SucursalList as IEnumerable<SelectListItem>;

            Assert.AreEqual(2, sucursales.Count());
            Assert.IsTrue(sucursales.Any(i => i.Text == "Suc1 (10)"));
            Assert.IsTrue(sucursales.Any(i => i.Text == "Suc2 (20)"));

            this.sucursalesRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void BulkSendShouldReturnPartialViewWhenAjaxRequest()
        {
            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.BulkSend() as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_BulkSend", result.ViewName);
        }

        [TestMethod]
        public void BulkSendShouldSaveImeis()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);
            var bulkSend = new BulkSendViewModel { Ids = "1", Comprobante = "REM 0001-00000001", FechaEnv = today, Imeis = "123456789123456", SucursalId = 1 };
            var result = controller.BulkSend(bulkSend) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void BulkSendShouldReturnPartialViewOnInvalidDate()
        {
            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });
            var bulkSend = new BulkSendViewModel { Ids = "1", Comprobante = "REM 0001-00000001", FechaEnv = today.AddDays(-1), Imeis = "123456789123456", SucursalId = 1 };

            var controller = this.CreateImeisController();
            var result = controller.BulkSend(bulkSend) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_BulkSend", result.ViewName);
        }

        [TestMethod]
        public void BulkReceiveShouldReturnEstadosInViewBag()
        {
            var controller = this.CreateImeisController();

            var result = controller.BulkReceive() as ViewResult;
            Assert.IsNotNull(result);

            var estados = result.ViewBag.EstadoList as IEnumerable<SelectListItem>;

            Assert.AreEqual(2, estados.Count());
            Assert.IsTrue(estados.Any(i => i.Text == "Disponible Venta"));
            Assert.IsTrue(estados.Any(i => i.Text == "Dañado"));
        }

        [TestMethod]
        public void BulkReceiveShouldReturnPartialViewWhenAjaxRequest()
        {
            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.BulkReceive() as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_BulkReceive", result.ViewName);
        }

        [TestMethod]
        public void BulkReceiveShouldSaveImeis()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);
            var bulkReceive = new BulkReceiveViewModel { Ids = "1", FechaRec = today, Imeis = "123456789123456" };
            var result = controller.BulkReceive(bulkReceive) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void BulkReceiveShouldReturnPartialViewOnInvalidDate()
        {
            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var controller = this.CreateImeisController();
            var bulkReceive = new BulkReceiveViewModel { Ids = "1", FechaRec = today.AddDays(-1), Imeis = "123456789123456" };
            var result = controller.BulkReceive(bulkReceive) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_BulkReceive", result.ViewName);
        }

        [TestMethod]
        public void SendImeiShouldReturnSucursalesInViewBag()
        {
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1", Direccion = "Dir1", Telefono = "Tel1" });
            this.sucursales.Add(new Sucursal { Id = 2, Codigo = "20", Nombre = "Suc2", Direccion = "Dir2", Telefono = "Tel2" });

            var controller = this.CreateImeisController();

            var result = controller.SendImei() as ViewResult;
            Assert.IsNotNull(result);

            var sucursales = result.ViewBag.SucursalList as IEnumerable<SelectListItem>;

            Assert.AreEqual(2, sucursales.Count());
            Assert.IsTrue(sucursales.Any(i => i.Text == "Suc1 (10)"));
            Assert.IsTrue(sucursales.Any(i => i.Text == "Suc2 (20)"));

            this.sucursalesRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void SendImeiShouldReturnPartialViewWhenAjaxRequest()
        {
            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.SendImei() as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_SendImei", result.ViewName);
        }

        [TestMethod]
        public void SendImeiShouldSaveImeis()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);
            var send = new SendImeiViewModel { Id = 1, Comprobante = "REM 0001-00000001", FechaEnv = today, Imei = 123456789123456, SucursalId = 1 };
            var result = controller.SendImei(send) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void SendImeiShouldReturnPartialViewOnInvalidDate()
        {
            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var controller = this.CreateImeisController();
            var send = new SendImeiViewModel { Id = 1, Comprobante = "REM 0001-00000001", FechaEnv = today.AddDays(-1), Imei = 123456789123456, SucursalId = 1 };
            var result = controller.SendImei(send) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_SendImei", result.ViewName);
        }

        [TestMethod]
        public void ReceiveImeiShouldReturnEstadosInViewBag()
        {
            var controller = this.CreateImeisController();

            var result = controller.ReceiveImei() as ViewResult;
            Assert.IsNotNull(result);

            var estados = result.ViewBag.EstadoList as IEnumerable<SelectListItem>;

            Assert.AreEqual(2, estados.Count());
            Assert.IsTrue(estados.Any(i => i.Text == "Disponible Venta"));
            Assert.IsTrue(estados.Any(i => i.Text == "Dañado"));
        }

        [TestMethod]
        public void ReceiveImeiShouldReturnPartialViewWhenAjaxRequest()
        {
            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.ReceiveImei() as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_ReceiveImei", result.ViewName);
        }

        [TestMethod]
        public void ReceiveImeiShouldSaveImeis()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);
            var receive = new ReceiveImeiViewModel { Id = 1, FechaRec = today, Imei = 123456789123456 };
            var result = controller.ReceiveImei(receive) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void ReceiveImeiShouldReturnPartialViewOnInvalidDate()
        {
            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1 });

            var controller = this.CreateImeisController();
            var receive = new ReceiveImeiViewModel { Id = 1, FechaRec = today.AddDays(-1), Imei = 123456789123456 };
            var result = controller.ReceiveImei(receive) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_ReceiveImei", result.ViewName);
        }

        [TestMethod]
        public void SellImeiShouldReturnAbonosForCelularWithOperador()
        {
            var marca = new Marca { Id = 2, Nombre = "Marca2", EsOperador = true };
            var cel = new Celular { Id = 1, MarcaId = 2, Marca = marca };

            this.celulares.Add(cel);
            this.abonos.Add(new Abono { Id = 1, Descripcion = "Abono1", MarcaId = 2, Operador = marca });
            this.abonos.Add(new Abono { Id = 2, Descripcion = "Abono2", MarcaId = 2, Operador = marca });

            var controller = this.CreateImeisController();

            var result = controller.SellImei(1) as ViewResult;
            Assert.IsNotNull(result);

            var abonos = result.ViewBag.AbonoList as IEnumerable<SelectListItem>;

            Assert.AreEqual(2, abonos.Count());
            Assert.IsTrue(abonos.Any(i => i.Text == "Abono1"));
            Assert.IsTrue(abonos.Any(i => i.Text == "Abono2"));

            this.abonosRepositoryMock.VerifyAll();
            this.celularesRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void SellImeiShouldReturnLiberadoAbonoForCelularWithoutOperador()
        {
            var marca = new Marca { Id = 2, Nombre = "Marca2", EsOperador = false };
            var cel = new Celular { Id = 1, MarcaId = 2, Marca = marca };

            this.celulares.Add(cel);
            this.marcas.Add(marca);

            var controller = this.CreateImeisController();

            var result = controller.SellImei(1) as ViewResult;
            Assert.IsNotNull(result);

            var abonos = result.ViewBag.AbonoList as IEnumerable<SelectListItem>;

            Assert.AreEqual(1, abonos.Count());
            Assert.IsTrue(abonos.Any(i => i.Text == "Liberado"));

            this.celularesRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void SellImeiShouldReturnPartialViewWhenAjaxRequest()
        {
            var marca = new Marca { Id = 2, Nombre = "Marca2", EsOperador = false };
            var cel = new Celular { Id = 1, MarcaId = 2, Marca = marca };

            this.celulares.Add(cel);
            this.marcas.Add(marca);

            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.SellImei(1) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_SellImei", result.ViewName);

            this.celularesRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void SellImeiShouldSaveSell()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            var marca = new Marca { Id = 1, Codigo = 10, Nombre = "Marca1" };
            var suc = new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" };
            this.marcas.Add(marca);
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1, Sucursal = suc });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456, Marca = marca, MarcaId = 1, Seguimientos = this.seguimientos });

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);
            var sell = new SellImeiViewModel { AbonoId = 1, Id = 1, Imei = 123456789123456, FechaVenta = today };
            var result = controller.SellImei(sell) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void SellImeiShouldReturnPartialViewOnInvalidDate()
        {
            var today = DateTime.Today;
            var marca = new Marca { Id = 1, Codigo = 10, Nombre = "Marca1" };
            var suc = new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" };
            this.marcas.Add(marca);
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1, Sucursal = suc });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456, Marca = marca, MarcaId = 1, Seguimientos = this.seguimientos });

            var controller = this.CreateImeisController();
            var sell = new SellImeiViewModel { AbonoId = 1, Id = 1, Imei = 123456789123456, FechaVenta = today.AddDays(-1) };
            var result = controller.SellImei(sell) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_SellImei", result.ViewName);
        }

        [TestMethod]
        public void ReturnImeiShouldReturnEstadosInViewBag()
        {
            var controller = this.CreateImeisController();

            var result = controller.ReturnImei() as ViewResult;
            Assert.IsNotNull(result);

            var estados = result.ViewBag.EstadoList as IEnumerable<SelectListItem>;

            Assert.AreEqual(2, estados.Count());
            Assert.IsTrue(estados.Any(i => i.Text == "Disponible Venta"));
            Assert.IsTrue(estados.Any(i => i.Text == "Dañado"));
        }

        [TestMethod]
        public void ReturnImeiShouldReturnPartialViewWhenAjaxRequest()
        {
            var controller = this.CreateImeisControllerWithAjaxRequest();
            var result = controller.ReturnImei() as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_ReturnImei", result.ViewName);
        }

        [TestMethod]
        public void ReturnImeiShouldSaveImeis()
        {
            this.userRole = Constants.AdministradorRole;
            this.isInRole = true;
            var sucursal = "Sucursal";
            var userName = "Asociante";

            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1, Estado = Estado.Vendido });

            var membershipUserMock = new Mock<MembershipUser>();
            membershipUserMock.Setup(u => u.ProviderUserKey).Returns(new Guid("00000000-0000-0000-0000-000000000000"));

            var membershipProviderMock = new Mock<MembershipProvider>();
            membershipProviderMock.Setup(m => m.GetUser(userName, true)).Returns(membershipUserMock.Object);

            var identityMock = new Mock<IIdentity>();
            identityMock.Setup(i => i.Name).Returns(userName);

            this.principalMock.Setup(p => p.Identity).Returns(identityMock.Object);

            var roleProviderMock = new Mock<RoleProvider>();
            roleProviderMock.Setup(rp => rp.GetRolesForUser(userName)).Returns(new[] { string.Concat(sucursal, Constants.SucursalRoleSuffix) });

            var controller = this.CreateImeisController(membershipProviderMock.Object, roleProviderMock.Object);
            var ret = new ReturnImeiViewModel { Id = 1, Imei = 123456789123456, FechaDev = today };
            var result = controller.ReturnImei(ret) as JsonResult;
            Assert.IsNotNull(result);

            var json = result.Data.ToString();
            Assert.AreEqual("{ saved = True }", json);
        }

        [TestMethod]
        public void ReturnImeiShouldReturnPartialViewOnInvalidDate()
        {
            var today = DateTime.Today;
            this.sucursales.Add(new Sucursal { Id = 1, Codigo = "10", Nombre = "Suc1" });
            this.celulares.Add(new Celular { Id = 1, Imei = 123456789123456 });
            this.seguimientos.Add(new Seguimiento { Id = 1, CelularId = 1, Fecha = today, SucursalId = 1, Estado = Estado.Vendido });

            var controller = this.CreateImeisController();
            var ret = new ReturnImeiViewModel { Id = 1, Imei = 123456789123456, FechaDev = today.AddDays(-1) };
            var result = controller.ReturnImei(ret) as PartialViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("_ReturnImei", result.ViewName);
        }

        [TestMethod]
        public void ListShouldReturnImeis()
        {
            DateTime today = DateTime.Today;
            this.celulares.Add(new Celular { Id = 1, FechaIngreso = DateTime.Today, MarcaId = 1, Imei = 123456789123456 });
            this.celulares.Add(new Celular { Id = 2, FechaIngreso = DateTime.Today, MarcaId = 1, Imei = 123456789123455 });

            var controller = this.CreateImeisController();

            var result = controller.List(string.Empty, 1, 50) as JsonResult;
            Assert.IsNotNull(result);

            var model = result.Data;
            Assert.IsNotNull(model);

            //// TODO: Deserialize Json and assert for specific content
        }

        [TestMethod]
        public void ListShouldReturnFilteredImeisWhenFilterIsNotEmpty()
        {
            DateTime today = DateTime.Today;
            this.celulares.Add(new Celular { Id = 1, FechaIngreso = DateTime.Today, MarcaId = 1, Imei = 123456789123456 });
            this.celulares.Add(new Celular { Id = 2, FechaIngreso = DateTime.Today, MarcaId = 1, Imei = 123456789123455 });

            var controller = this.CreateImeisController();

            var result = controller.List("imei:1+producto:samsung+ingreso:2012-12-12+operador:claro+estado:Pendiente+ubicacion:almagro+comprobante:1", 1, 50) as JsonResult;
            Assert.IsNotNull(result);

            var model = result.Data;
            Assert.IsNotNull(model);

            //// TODO: Deserialize Json and assert for specific content
        }

        private ImeisController CreateImeisController(MembershipProvider membershipProvider = null, RoleProvider roleProvider = null)
        {
            var httpContextMock = new Mock<HttpContextBase>();
            httpContextMock.Setup(c => c.User).Returns(() => this.principalMock.Object);
            httpContextMock.Setup(c => c.Request).Returns(new Mock<HttpRequestBase>().Object);
            httpContextMock.Setup(c => c.Response).Returns(new Mock<HttpResponseBase>().Object);

            var httpContext = httpContextMock.Object;

            var routes = new RouteCollection();
            RouteConfig.RegisterRoutes(routes);

            var controller = new ImeisController(this.repositoriesMock.Object, membershipProvider, roleProvider)
            {
                ControllerContext = new ControllerContext { HttpContext = httpContext },
                Url = new UrlHelper(new RequestContext(httpContext, new RouteData()), routes),
            };

            return controller;
        }

        private ImeisController CreateImeisControllerWithAjaxRequest(MembershipProvider membershipProvider = null, RoleProvider roleProvider = null)
        {
            var httpContextMock = new Mock<HttpContextBase>();
            httpContextMock.Setup(c => c.User).Returns(() => this.principalMock.Object);
            var requestMock = new Mock<HttpRequestBase>();
            requestMock.Setup(r => r["X-Requested-With"]).Returns("XMLHttpRequest");
            httpContextMock.Setup(c => c.Request).Returns(requestMock.Object);
            httpContextMock.Setup(c => c.Response).Returns(new Mock<HttpResponseBase>().Object);

            var httpContext = httpContextMock.Object;

            var routes = new RouteCollection();
            RouteConfig.RegisterRoutes(routes);

            var controller = new ImeisController(this.repositoriesMock.Object, membershipProvider, roleProvider)
            {
                ControllerContext = new ControllerContext { HttpContext = httpContext },
                Url = new UrlHelper(new RequestContext(httpContext, new RouteData()), routes),
            };

            return controller;
        }
    }
}
